2023/12/231938字符

响应缓存体

index.js
const express = require("express");

const app = express();
app.use(express.static("./public"));

const router = express.Router();

router.get("/:id", require("./cache")({ ttl: 10 }), (req, res) => {
    console.log(req.originalUrl, "没有使用缓存");
    // 从数据库中取出对应id的新闻数据
    res.send({
        title: "新闻标题" + req.params.id,
        content: "新闻内容" + req.params.id,
    });
});

app.use("/api/news", router);

app.listen(9527);
cache.js
const redis = require("redis");
const client = redis.createClient();
const { promisify } = require("util");

const getAsync = promisify(client.get).bind(client);
const setAsync = promisify(client.set).bind(client);

module.exports = function (options = {}) {
    // 缓存的数据是否是json格式
    const isJSON = options.isJSON === undefined ? true : options.isJSON;
    const ttl = options.ttl || -1;
    return async function (req, res, next) {
        const key = req.originalUrl;

        const content = await getAsync(key);
        if (content) {
            // 有缓存
            console.log(key, "使用了缓存");
            const body = isJSON ? JSON.parse(content) : content;
            res.send(body);
        } else {
            // 没有缓存
            // 如何获取后续响应中的响应体
            // express写响应体,最终是通过 res.write 函数完成
            const defaultWrite = res.write.bind(res),
                defaultEnd = res.end.bind(res);
            const chunks = [];
            res.write = function (chunk, ...args) {
                chunks.push(chunk);
                defaultWrite(chunk, ...args);
            };
            res.end = function (chunk, ...args) {
                if (chunk) {
                    chunks.push(chunk);
                }
                const body = chunks.map((c) => c.toString("utf-8")).join();
                if (ttl < 0) {
                    setAsync(key, body);
                } else {
                    setAsync(key, body, "EX", ttl);
                }

                defaultEnd(chunk, ...args);
            };
            next();
        }
    };
};